/**
 * 蓝牙通信工具类
 * 实现BLE设备发现、连接和数据传输
 * 与安卓版本保持一致的数据结构和逻辑
 */

// 设备发现类型枚举（与安卓版本一致）
const DiscoveryType = {
  CONNECTED: 'CONNECTED',
  PAIRED: 'PAIRED', 
  DISCOVERED: 'DISCOVERED'
}

// 蓝牙类型枚举（与安卓版本一致）
const BluetoothType = {
  CLASSIC: 'CLASSIC',
  LOW_ENERGY: 'LOW_ENERGY'
}

// 设备数据结构（与安卓版本DiscoveredDevice一致）
class DiscoveredDevice {
  constructor(name, bluetoothAddress, discoveryType, bluetoothType) {
    this.name = name
    this.bluetoothAddress = bluetoothAddress
    this.discoveryType = discoveryType
    this.bluetoothType = bluetoothType
  }

  static fromWxDevice(wxDevice, discoveryType, bluetoothType) {
    return new DiscoveredDevice(
      wxDevice.name || '未知设备',
      wxDevice.deviceId || '',
      discoveryType,
      bluetoothType
    )
  }
}

class BluetoothManager {
  constructor() {
    this.isConnected = false
    this.deviceId = null
    this.deviceName = null
    this.serviceId = null
    this.characteristicId = null
    this.onDataReceived = null
    this.onConnectionStateChange = null
    this.onDeviceFound = null
    this.chineseType = 'gbk' // utf8 or gbk
    
    // 设备列表管理（与安卓版本一致）
    this.devices = new Map() // 按设备地址存储
    this.discoveryCallbacks = []
    
    // 扫描状态管理
    this.isScanning = false
    this.scanStartTime = null
    this.deviceFoundCallback = null
  }

  // 初始化蓝牙
  async init() {
    try {
      const res = await wx.openBluetoothAdapter()
      
      // 监听蓝牙适配器状态变化
      wx.onBluetoothAdapterStateChange((res) => {
        if (!res.available) {
          // 蓝牙不可用
        }
        if (!res.discovering) {
          // 蓝牙停止发现
          this.isScanning = false
        }
      })
      
      return true
    } catch (error) {
      console.error('蓝牙初始化失败:', error)
      return false
    }
  }

  // 开始扫描设备（与安卓版本一致）
  async startScan(discoveryType = DiscoveryType.DISCOVERED) {
    try {
      // 如果已经在扫描，先停止
      if (this.isScanning) {
        await this.stopScan()
        // 等待一下再开始新扫描
        await new Promise(resolve => setTimeout(resolve, 1000))
      }
      
      // 设置扫描参数，提高设备发现率
      const scanOptions = {
        allowDuplicatesKey: true, // 允许重复设备，提高发现率
        // 不设置services过滤，扫描所有设备
        services: [],
        // 设置扫描间隔，平衡发现率和功耗
        interval: 0, // 0表示使用系统默认值
        // 设置功率模式，提高发现率
        powerLevel: 'high',
        success: (res) => {
          this.isScanning = true
          this.scanStartTime = Date.now()
        },
        fail: (error) => {
          console.error('扫描失败:', error)
          this.isScanning = false
          throw error
        }
      }
      
      await wx.startBluetoothDevicesDiscovery(scanOptions)
      
      // 设置设备发现监听器
      this.setupDeviceFoundListener()
      
      return true
    } catch (error) {
      console.error('开始扫描异常:', error)
      this.isScanning = false
      throw error
    }
  }

  // 停止扫描
  async stopScan() {
    try {
      await wx.stopBluetoothDevicesDiscovery()
      this.isScanning = false
      this.scanStartTime = null
    } catch (error) {
      console.error('停止扫描失败:', error)
      this.isScanning = false
    }
  }

  // 设置设备发现监听器
  setupDeviceFoundListener() {
    // 移除之前的监听器
    wx.offBluetoothDeviceFound()
    
    // 设置新的监听器
    wx.onBluetoothDeviceFound((res) => {
      const devices = res.devices
      
      if (devices.length === 0) {
        return
      }
      
      devices.forEach((wxDevice, index) => {
        // 过滤无效设备
        if (!this.isValidDevice(wxDevice)) {
          return
        }
        
        // 转换为与安卓版本一致的数据结构
        const discoveredDevice = DiscoveredDevice.fromWxDevice(
          wxDevice, 
          DiscoveryType.DISCOVERED, 
          this.getBluetoothType(wxDevice)
        )
        
        // 添加额外信息
        discoveredDevice.RSSI = wxDevice.RSSI
        discoveredDevice.advertisData = wxDevice.advertisData
        discoveredDevice.advertisServiceUUIDs = wxDevice.advertisServiceUUIDs
        discoveredDevice.localName = wxDevice.localName
        discoveredDevice.serviceData = wxDevice.serviceData
        
        // 检测是否为GAIA设备
        discoveredDevice.isGaiaDevice = this.isGaiaDevice(discoveredDevice)
        
        // 添加信号强度等级
        discoveredDevice.signalLevel = this.getSignalLevel(wxDevice.RSSI)
        
        // 添加设备类型标识
        discoveredDevice.deviceType = this.getDeviceType(wxDevice)
        
        // 调用回调函数
        if (this.deviceFoundCallback) {
          this.deviceFoundCallback(discoveredDevice)
        }
      })
    })
  }

  // 监听设备发现（与安卓版本一致）
  setOnDeviceFound(callback) {
    this.deviceFoundCallback = callback
  }

  // 获取蓝牙类型（与安卓版本一致）
  getBluetoothType(wxDevice) {
    // 微信小程序中，所有设备都是低功耗蓝牙
    return BluetoothType.LOW_ENERGY
  }

  // 检测是否为GAIA设备（与安卓版本逻辑一致）
  isGaiaDevice(device) {
    // 方法1: 通过设备名称关键词识别
    const gaiaKeywords = [
      'GAIA', 'CSR', 'Qualcomm', 'QCC', 'BCM', 'Broadcom',
      'TWS', 'EARBUDS', 'HEADPHONES', 'EARPHONES', 'BUDS',
      'SOUNDCORE', 'LIBERTY', 'LIFE', 'PURE', 'SPIRIT',
      'AUDIO', 'MUSIC', 'SOUND', 'WIRELESS', 'BLUETOOTH'
    ]
    const deviceName = (device.name || '').toUpperCase()
    
    // 检查设备名称是否包含GAIA关键词
    const hasGaiaKeyword = gaiaKeywords.some(keyword => deviceName.includes(keyword))
    
    // 方法2: 通过广播数据识别GAIA服务
    let hasGaiaService = false
    if (device.advertisServiceUUIDs && device.advertisServiceUUIDs.length > 0) {
      const gaiaServiceUUIDs = [
        '00001100-D102-11E1-9B23-00025B00A5A5', // GATT GAIA服务
        '00001107-D102-11E1-9B23-00025B00A5A5', // RFCOMM GAIA Legacy
        '00001101-0000-1000-8000-00805F9B34FB'  // SPP服务
      ]
      
      hasGaiaService = device.advertisServiceUUIDs.some(uuid => {
        const deviceUuid = uuid.toUpperCase()
        return gaiaServiceUUIDs.some(gaiaUuid => 
          deviceUuid.includes(gaiaUuid.replace(/-/g, '').substring(0, 8))
        )
      })
    }
    
    // 方法3: 通过设备类型识别（排除明显非GAIA的设备）
    const nonGaiaTypes = ['PHONE', 'COMPUTER', 'LAPTOP', 'PC', 'MOBILE', 'SAMSUNG', 'IPHONE', 'HUAWEI', 'XIAOMI']
    const isNonGaiaType = nonGaiaTypes.some(type => deviceName.includes(type))
    
    // 综合判断：有GAIA关键词或GAIA服务，且不是明显非GAIA的设备类型
    const isGaiaDevice = (hasGaiaKeyword || hasGaiaService) && !isNonGaiaType
    
    return isGaiaDevice
  }

  // 验证设备是否有效
  isValidDevice(wxDevice) {
    // 检查设备ID是否存在
    if (!wxDevice.deviceId) {
      return false
    }
    
    // 放宽设备名称检查 - 允许空名称或未知设备
    if (wxDevice.name === 'null' || wxDevice.name === 'undefined') {
      return false
    }
    
    // 检查信号强度是否过低（放宽条件）
    if (wxDevice.RSSI && wxDevice.RSSI < -100) {
      return false
    }
    
    // 移除系统设备过滤，允许所有设备
    // 只过滤掉一些明显无效的设备名称
    const invalidNames = ['', 'null', 'undefined', 'unknown']
    if (invalidNames.includes(wxDevice.name)) {
      return false
    }
    
    return true
  }

  // 获取信号强度等级
  getSignalLevel(rssi) {
    if (!rssi) return 'unknown'
    
    if (rssi >= -50) return 'excellent'
    if (rssi >= -60) return 'good'
    if (rssi >= -70) return 'fair'
    if (rssi >= -80) return 'poor'
    return 'very_poor'
  }

  // 获取设备类型
  getDeviceType(wxDevice) {
    const name = (wxDevice.name || '').toLowerCase()
    
    // 耳机设备
    if (name.includes('headphone') || name.includes('earbud') || name.includes('earphone') || 
        name.includes('airpods') || name.includes('buds') || name.includes('tws')) {
      return 'headphone'
    }
    
    // 音箱设备
    if (name.includes('speaker') || name.includes('soundbar') || name.includes('audio')) {
      return 'speaker'
    }
    
    // 手机设备
    if (name.includes('phone') || name.includes('mobile') || name.includes('samsung') || 
        name.includes('iphone') || name.includes('huawei') || name.includes('xiaomi')) {
      return 'phone'
    }
    
    // 电脑设备
    if (name.includes('pc') || name.includes('laptop') || name.includes('computer') || 
        name.includes('macbook') || name.includes('thinkpad')) {
      return 'computer'
    }
    
    return 'unknown'
  }

  // 连接设备
  async connectDevice(deviceId, deviceName = null) {
    try {
      // 检查是否已经连接到同一个设备
      if (this.isConnected && this.deviceId === deviceId) {
        return { success: true, alreadyConnected: true }
      }

      // 检查是否已经连接到不同的设备
      if (this.isConnected && this.deviceId !== deviceId) {
        await this.disconnect()
        // 等待断开连接完成
        await new Promise(resolve => setTimeout(resolve, 1000))
      }

      // 检查设备是否已经连接（微信小程序层面）
      try {
        const connectedDevices = await wx.getConnectedBluetoothDevices({
          services: []
        })
        const isAlreadyConnected = connectedDevices.devices.some(device => device.deviceId === deviceId)
        
        if (isAlreadyConnected) {
          this.deviceId = deviceId
          this.deviceName = deviceName
          this.isConnected = true
          this.onConnectionStateChange && this.onConnectionStateChange(true)
          return { success: true, alreadyConnected: true }
        }
      } catch (error) {
        // 检查已连接设备失败，继续连接流程
      }

      // 创建新连接
      await new Promise((resolve, reject) => {
        wx.createBLEConnection({
          deviceId: deviceId,
          success: (res) => {
            this.deviceId = deviceId
            this.deviceName = deviceName
            this.isConnected = true
            this.onConnectionStateChange && this.onConnectionStateChange(true)
            resolve(res)
          },
          fail: (error) => {
            console.error('连接失败:', error)
            this.onConnectionStateChange && this.onConnectionStateChange(false)
            reject(error)
          }
        })
      })

      // 等待连接稳定
      await new Promise(resolve => setTimeout(resolve, 500))

      return { success: true, alreadyConnected: false }
    } catch (error) {
      console.error('连接异常:', error)
      throw error
    }
  }

  // 断开连接
  async disconnect() {
    if (this.deviceId) {
      try {
        await wx.closeBLEConnection({
          deviceId: this.deviceId
        })
        this.isConnected = false
        this.deviceId = null
        this.deviceName = null
        this.onConnectionStateChange && this.onConnectionStateChange(false)
      } catch (error) {
        console.error('断开连接失败:', error)
      }
    }
  }

  // 获取设备服务
  async getServices(deviceId) {
    try {
      const res = await wx.getBLEDeviceServices({
        deviceId: deviceId
      })
      return res.services
    } catch (error) {
      console.error('获取服务失败:', error)
      return []
    }
  }

  // 获取特征值
  async getCharacteristics(deviceId, serviceId) {
    try {
      const res = await wx.getBLEDeviceCharacteristics({
        deviceId: deviceId,
        serviceId: serviceId
      })
      return res.characteristics
    } catch (error) {
      console.error('获取特征值失败:', error)
      return []
    }
  }

  // 监听特征值变化
  async notifyCharacteristicValueChange(deviceId, serviceId, characteristicId) {
    try {
      await wx.notifyBLECharacteristicValueChange({
        deviceId: deviceId,
        serviceId: serviceId,
        characteristicId: characteristicId,
        state: true
      })
      
      wx.onBLECharacteristicValueChange((res) => {
        const value = res.value
        const hexValue = this.arrayBufferToHex(value)
        const textValue = this.arrayBufferToString(value)
        console.log('收到数据22:', {
          hex: hexValue,
          text: textValue
        })
        this.onDataReceived && this.onDataReceived(textValue, hexValue)
      })
      
      this.serviceId = serviceId
      this.characteristicId = characteristicId
      return true
    } catch (error) {
      console.error('监听特征值失败:', error)
      return false
    }
  }

  // 写入数据
  async writeData(data, isHex = true) {
    if (!this.deviceId || !this.serviceId || !this.characteristicId) {
      console.error('设备未连接或特征值未设置')
      return false
    }

    try {
      let buffer
      if (isHex) {
        buffer = this.hexToArrayBuffer(data)
      } else {
        buffer = this.stringToArrayBuffer(data)
      }

      await wx.writeBLECharacteristicValue({
        deviceId: this.deviceId,
        serviceId: this.serviceId,
        characteristicId: this.characteristicId,
        value: buffer
      })
      
      return true
    } catch (error) {
      console.error('写入数据失败:', error)
      return false
    }
  }

  // 设置字符编码类型
  setChineseType(type) {
    this.chineseType = type
  }

  // ArrayBuffer转十六进制字符串
  arrayBufferToHex(buffer) {
    const uint8Array = new Uint8Array(buffer)
    let hex = ''
    for (let i = 0; i < uint8Array.length; i++) {
      hex += uint8Array[i].toString(16).padStart(2, '0')
    }
    return hex
  }

  // ArrayBuffer转字符串
  arrayBufferToString(buffer) {
    const uint8Array = new Uint8Array(buffer)
    let str = ''
    for (let i = 0; i < uint8Array.length; i++) {
      str += String.fromCharCode(uint8Array[i])
    }
    return str
  }

  // 十六进制字符串转ArrayBuffer
  hexToArrayBuffer(hex) {
    const buffer = new ArrayBuffer(hex.length / 2)
    const uint8Array = new Uint8Array(buffer)
    for (let i = 0; i < hex.length; i += 2) {
      uint8Array[i / 2] = parseInt(hex.substr(i, 2), 16)
    }
    return buffer
  }

  // 字符串转ArrayBuffer
  stringToArrayBuffer(str) {
    const buffer = new ArrayBuffer(str.length)
    const uint8Array = new Uint8Array(buffer)
    for (let i = 0; i < str.length; i++) {
      uint8Array[i] = str.charCodeAt(i)
    }
    return buffer
  }

  // 设置数据接收回调
  setOnDataReceived(callback) {
    this.onDataReceived = callback
  }

  // 设置连接状态变化回调
  setOnConnectionStateChange(callback) {
    this.onConnectionStateChange = callback
  }


  // 关闭蓝牙适配器
  async close() {
    try {
      // 先停止扫描
      if (this.isScanning) {
        await this.stopScan()
      }
      
      // 断开连接
      if (this.isConnected) {
        await this.disconnect()
      }
      
      // 关闭适配器
      await wx.closeBluetoothAdapter()
      return true
    } catch (error) {
      console.error('关闭蓝牙适配器失败:', error)
      return false
    }
  }

  // 获取扫描状态
  getScanningStatus() {
    return this.isScanning
  }

  // 获取扫描持续时间
  getScanDuration() {
    if (!this.scanStartTime) return 0
    return Math.floor((Date.now() - this.scanStartTime) / 1000)
  }

  // 获取已发现的设备列表
  async getDiscoveredDevices() {
    try {
      const res = await wx.getBluetoothDevices()
      return res.devices || []
    } catch (error) {
      console.error('获取已发现设备列表失败:', error)
      return []
    }
  }

  // 获取已连接的设备列表
  async getConnectedDevices() {
    try {
      const res = await wx.getConnectedBluetoothDevices({
        services: []
      })
      return res.devices || []
    } catch (error) {
      console.error('获取已连接设备列表失败:', error)
      return []
    }
  }
}

// 创建单例实例
const bluetoothManager = new BluetoothManager()

// 导出枚举和类
module.exports = {
  DiscoveryType,
  BluetoothType,
  DiscoveredDevice,
  bluetoothManager
}

// 同时支持直接导出实例（向后兼容）
module.exports.default = bluetoothManager

// 确保default导出正确
module.exports = bluetoothManager
module.exports.DiscoveryType = DiscoveryType
module.exports.BluetoothType = BluetoothType
module.exports.DiscoveredDevice = DiscoveredDevice
module.exports.bluetoothManager = bluetoothManager
